package xyz.wbsite.screen.client;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.system.SystemUtil;

import javax.swing.filechooser.FileSystemView;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;

public class ShortCutUtil {

    /**
     * 文件头，固定字段
     */
    private static byte[] headFile = {0x4c, 0x00, 0x00, 0x00,
            0x01, 0x14, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
            (byte) 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46
    };
    /**
     * 文件头属性
     */
    private static byte[] fileAttributes = {(byte) 0x93, 0x00, 0x08, 0x00,//可选文件属性
            0x20, 0x00, 0x00, 0x00,//目标文件属性
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,//文件创建时间
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,//文件修改时间
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,//文件最后一次访问时间
            0x00, 0x00, 0x00, 0x00,//文件长度
            0x00, 0x00, 0x00, 0x00,//自定义图标个数
            0x01, 0x00, 0x00, 0x00,//打开时窗口状态
            0x00, 0x00, 0x00, 0x00,//热键
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00//未知
    };
    /**
     * 固定字段1
     */
    static byte[] fixedValueOne = {
            (byte) 0x83, 0x00, 0x14, 0x00
            , 0x1F, 0x50, (byte) 0xE0, 0x4F
            , (byte) 0xD0, 0x20, (byte) 0xEA
            , 0x3A, 0x69, 0x10, (byte) 0xA2
            , (byte) 0xD8, 0x08, 0x00, 0x2B
            , 0x30, 0x30, (byte) 0x9D, 0x19, 0x00, 0x2f
    };
    /**
     * 固定字段2
     */
    static byte[] fixedValueTwo = {
            0x3A, 0x5C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
            , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
            , 0x00, 0x54, 0x00, 0x32, 0x00, 0x04
            , 0x00, 0x00, 0x00, 0x67, 0x50, (byte) 0x91, 0x3C, 0x20, 0x00
    };

    /**
     * 复制文件
     *
     * @param source
     * @param dest
     * @throws IOException
     */
    private static void copyFileUsingFileChannels(File source, File dest) throws IOException {
        FileChannel inputChannel = null;
        FileChannel outputChannel = null;
        try {
            inputChannel = new FileInputStream(source).getChannel();
            outputChannel = new FileOutputStream(dest).getChannel();
            outputChannel.transferFrom(inputChannel, 0, inputChannel.size());
        } finally {
            inputChannel.close();
            outputChannel.close();
        }
    }

    /**
     * 创建快捷方式
     *
     * @param lnk    快捷方式文件路径
     * @param target 目标文件(exe,path,bat...)
     */
    public static void createShortCut(File lnk, File target) {
        if (!SystemUtil.getOsInfo().isWindows()) {
            System.out.println("当前系统不是window系统,无法创建快捷方式!!");
            return;
        }

        try {
            File touch = FileUtil.touch(lnk);
            BufferedOutputStream stream = FileUtil.getOutputStream(touch);
            stream.write(headFile);
            stream.write(fileAttributes);
            stream.write(fixedValueOne);
            stream.write((target.getAbsolutePath().toCharArray()[0] + "").getBytes());
            stream.write(fixedValueTwo);
            stream.write(target.getAbsolutePath().substring(3).getBytes("gbk"));
            stream.flush();
            IoUtil.close(stream);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 在目标位置创建快捷方式
     *
     * @param target 目标
     */
    public static File createShortCut(File target) {
        File lnk = new File(target.getParentFile(), FileUtil.mainName(target) + ".lnk");
        createShortCut(lnk, target);
        return lnk;
    }

    /**
     * 在桌面创建快捷方式
     *
     * @param target 目标
     */
    public static File createShortCutForDesktop(File target) {
        File lnk = new File(FileSystemView.getFileSystemView().getHomeDirectory(), FileUtil.mainName(target) + ".lnk");
        createShortCut(lnk, target);
        return lnk;
    }

    /**
     * 设置某软件开启启动
     *
     * @param targetFile 源文件
     * @return 是否设置成功
     */
    public static boolean setStartup(File targetFile, boolean forAllUser) {
        File shortCut = createShortCut(targetFile);
        // 用户启动目录
        String userStartup = System.getProperty("user.home") + "\\AppData\\Roaming\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\\";
        // 系统启动目录
        String sysStartup = "C:\\ProgramData\\Microsoft\\Windows\\Start Menu\\Programs\\Startup";
        String startup = forAllUser ? sysStartup : userStartup;
        // 快捷方式复制到启动目录
        FileUtil.copy(shortCut, new File(startup, shortCut.getName()), true);
        return true;
    }

    public static boolean delStartup(File targetFile, boolean forAllUser) {
        File shortCut = createShortCut(targetFile);
        // 用户启动目录
        String userStartup = System.getProperty("user.home") + "\\AppData\\Roaming\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\\";
        // 系统启动目录
        String sysStartup = "C:\\ProgramData\\Microsoft\\Windows\\Start Menu\\Programs\\Startup";
        String startup = forAllUser ? sysStartup : userStartup;
        FileUtil.del(new File(startup, shortCut.getName()));
        return true;
    }

    /**
     * 设置软件开机启动
     *
     * @param targetFile 源文件
     * @return 是否设置成功
     */
    public static boolean setStartup(File targetFile) {
        return setStartup(targetFile, false);
    }

    /**
     * 删除软件开机启动
     *
     * @param targetFile 源文件
     * @return 是否设置成功
     */
    public static boolean delStartup(File targetFile) {
        return delStartup(targetFile, false);
    }
}
